﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using IceDog.DNC.Program.WebApi.Models;
using IceDog.DNC.Program.WebApi.Repositories;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;

namespace IceDog.DNC.Program.WebApi.Controllers
{
    /// <summary>
    /// 使用传统的api方式，通过get或post请求来处理controller/action模式
    /// </summary>
    //这里是中括号 [] 不是花括号 {}
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestsController : ControllerBase
    {
        private readonly IHostingEnvironment _env;
        private readonly IServiceProvider _provider;
        private readonly IStringRepository _stringRepository;
        private readonly SiteConfig _siteConfig;

        public TestsController(IHostingEnvironment env, IServiceProvider provider, IStringRepository stringRepository, IOptions<SiteConfig> siteconfig)
        {
            _env = env;
            _provider = provider;
            _stringRepository = stringRepository;
            _siteConfig = siteconfig.Value;
        }

        /// <summary>
        ///     GET test content
        /// </summary>
        /// <example>
        ///     GET api/tests 
        /// </example> 
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> Get()
        {
            return "test content";
        }

        public ActionResult<DateTime> GetCurrentDateTime()
        {
            return DateTime.Now;
        }

        public JsonResult GetEnvInfo()
        {
            return new JsonResult(_env);
        }

        /// <summary>
        /// 测试jsonP
        /// </summary>
        /// <returns></returns>
        public ActionResult<string> GetPersonInfo()
        {
            return "getPersonInfo({\"Name\": \"Cheeso\", \"Id\" : 1823, \"Rank\": 7})";
        }

        /// <summary>
        /// test service container singleton
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public JsonResult TestServiceContainerSingleton()
        {
            //我们对IOperationRepositorySingleton注册了三次，最后获取两次，
            //要注意到我们获取到的始终都是我们最后一次注册的那个给了一个Guid的实例，前面的会被覆盖。
            IServiceCollection services = new ServiceCollection();
            // 默认构造
            services.AddSingleton<IOperationRepositorySingleton, OperationRepository>();
            // 自定义传入Guid空值
            services.AddSingleton<IOperationRepositorySingleton>(
                new OperationRepository(Guid.Empty));
            // 自定义传入一个New的Guid
            services.AddSingleton<IOperationRepositorySingleton>(
                new OperationRepository(Guid.NewGuid()));

            IServiceProvider provider = services.BuildServiceProvider();
            // 输出singletone1的Guid
            var singletone1 = provider.GetService<IOperationRepositorySingleton>();
            // 输出singletone2的Guid
            var singletone2 = provider.GetService<IOperationRepositorySingleton>();
            return new JsonResult(new
            {
                signletone1 = singletone1.OperationId,
                signletone2 = singletone2.OperationId,
                equals = $"singletone1 == singletone2 ?{singletone1 == singletone2 }"
            });
        }

        /// <summary>
        /// test service container tranisent 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public JsonResult TestServiceContainerTranisent()
        {
            IServiceCollection services = new ServiceCollection();
            // 自定义传入一个New的Guid
            services.AddTransient<IOperationRepositoryTransient, OperationRepository>();

            IServiceProvider provider = services.BuildServiceProvider();
            // 输出tranisent1的Guid
            var tranisent1 = provider.GetService<IOperationRepositoryTransient>();
            // 输出tranisent2的Guid
            var tranisent2 = provider.GetService<IOperationRepositoryTransient>();
            return new JsonResult(new
            {
                tranisent1 = tranisent1.OperationId,
                tranisent2 = tranisent2.OperationId,
                equals = $"tranisent1 == tranisent2 ?{tranisent1 == tranisent2 }"
            });
        }

        /// <summary>
        /// test service container scoped 
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public JsonResult TestServiceContainerScoped()
        {
            //总共生成了4个Transient实例，2个Scope实例，1个Singleton实例。
            var services = new ServiceCollection()
                .AddScoped<IOperationRepositoryScoped, OperationRepository>()
                .AddTransient<IOperationRepositoryTransient, OperationRepository>()
                .AddSingleton<IOperationRepositorySingleton, OperationRepository>();
            var provider = services.BuildServiceProvider();
            var dict = new Dictionary<string, Guid>();
            using (var scope = provider.CreateScope())
            {
                var innerProvider = scope.ServiceProvider;
                var scoped1 = innerProvider.GetService<IOperationRepositoryScoped>();
                var transient1 = innerProvider.GetService<IOperationRepositoryTransient>();
                var singleton1 = innerProvider.GetService<IOperationRepositorySingleton>();

                var scopeobj2 = innerProvider.GetService<IOperationRepositoryScoped>();
                var transient2 = innerProvider.GetService<IOperationRepositoryTransient>();
                var singleton2 = innerProvider.GetService<IOperationRepositorySingleton>();

                dict["scope1"] = scoped1.OperationId;
                dict["transient1"] = transient1.OperationId;
                dict["singleton1"] = singleton1.OperationId;

                dict["scope2"] = scopeobj2.OperationId;
                dict["transient2"] = transient2.OperationId;
                dict["singleton2"] = singleton2.OperationId;
            }

            using (var scope = provider.CreateScope())
            {
                var innerProvider = scope.ServiceProvider;
                var scoped3 = innerProvider.GetService<IOperationRepositoryScoped>();
                var transient3 = innerProvider.GetService<IOperationRepositoryTransient>();
                var singleton3 = innerProvider.GetService<IOperationRepositorySingleton>();

                var scopeobj4 = innerProvider.GetService<IOperationRepositoryScoped>();
                var transient4 = innerProvider.GetService<IOperationRepositoryTransient>();
                var singleton4 = innerProvider.GetService<IOperationRepositorySingleton>();

                dict["scope3"] = scoped3.OperationId;
                dict["transient3"] = transient3.OperationId;
                dict["singleton3"] = singleton3.OperationId;

                dict["scope4"] = scopeobj4.OperationId;
                dict["transient4"] = transient4.OperationId;
                dict["singleton4"] = singleton4.OperationId;
            }
            return new JsonResult(dict);
        }

        /// <summary>
        /// test string repository
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> TestStringRepository(string text = "AbC", bool upper = false)
        {
            var rep = _provider.GetService<IStringRepository>();
            return upper ? rep.ToUpper(text) : rep.ToLower(text);
        }

        /// <summary>
        /// test string repository2
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> TestStringRepository2(string text = "AbC", bool upper = false)
        {
            var rep = _stringRepository;
            return upper ? rep.ToUpper(text) : rep.ToLower(text);
        }

        /// <summary>
        /// 通过 HttpContext来获取实例，不推荐，但是可以使用
        /// </summary>
        /// <param name="text">text</param>
        /// <param name="upper">is upper</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> TestHttpContext(string text = "AbC", bool upper = false)
        {
            var rep = HttpContext.RequestServices.GetService<IStringRepository>();
            return upper ? rep.ToUpper(text) : rep.ToLower(text);
        }

        /// <summary>
        /// 获取环境的路径
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> GetEnvironmentPath()
        {
            return Environment.CurrentDirectory;
        }

        /// <summary>
        /// 获取站点配置信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult<string> GetSiteConfig()
        {
            return JsonConvert.SerializeObject(_siteConfig);
        }

        /// <summary>
        /// 无返回体的请求
        /// </summary>
        [HttpGet]
        public void VoidRequest()
        {
        }

        /// <summary>
        /// 仅仅返回一个只有头的响应
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage HttpResponseMessageRequest()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("hello", Encoding.UTF8)
            };
            response.Headers.CacheControl = new CacheControlHeaderValue()
            {
                MaxAge = TimeSpan.FromMinutes(20)
            };
            response.Headers.Add("IceDog-Tag-1", "this is a custom tag");
            return response;
        }

        /// <summary>
        /// 返回一串数字
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public HttpResponseMessage HttpResponseMessageRequestNumberList()
        {
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new StringContent("[1,2,3]",Encoding.UTF8,"application/json")
            };
            return response;
        }
    }
}